iT邦幫忙

2025 iThome 鐵人賽

DAY 26
0
Rust

用 Tauri 打造你的應用程式系列 第 26

[Day 26] Plugin (八):Updater

  • 分享至 

  • xImage
  •  

在現代桌面應用開發中,自動更新機制已成為必備功能。它不僅能確保使用者始終使用最新版本,還能及時修復安全漏洞和錯誤。Tauri 2.0 提供了完整的自動更新解決方案,讓開發者能夠輕鬆為 Windows 應用程式加入專業級的更新功能。

更新流程概述

Tauri 的自動更新機制採用了安全且高效的設計:

  1. 版本檢查:應用程式啟動時,向指定的伺服器請求包含最新版本資訊的 JSON 檔案
  2. 版本比較:Tauri 自動比較本地版本與遠端版本號
  3. 安全下載:發現新版本時,下載更新包並驗證數位簽章
  4. 使用者確認:提示使用者是否要安裝更新,尊重使用者選擇

基本設定

首先在 tauri.conf.json 中啟用更新功能:

{
  "bundle": {
    "createUpdaterArtifacts": true
  },
  "plugins": {
    "updater": {
      "pubkey": "CONTENT FROM PUBLICKEY.PEM",
      "endpoints": [
        "https://releases.myapp.com/{{target}}/{{arch}}/{{current_version}}",
        // or a static github json file
        "https://github.com/user/repo/releases/latest/download/latest.json"
      ]
    }
  }
}
  • 這邊的 pubkey 就是數位簽章時使用的公鑰 (public key) ,這部分下一個段落會進行說明
  • endpoints 就是指伺服器端,用來提供 JSON 檔。

伺服器端需要提供一個 JSON 檔案,包含最新版本資訊:

{
  "version": "",
  "notes": "",
  "pub_date": "",
  "platforms": {
    "linux-x86_64": {
      "signature": "",
      "url": ""
    },
    "windows-x86_64": {
      "signature": "",
      "url": ""
    },
    "darwin-x86_64": {
      "signature": "",
      "url": ""
    }
  }
}

Updater 相關設定如果有完成的話,在打包後會有額外的 .sig 檔案產生,就是上面 JSON 內的 signature

金鑰

自動更新最重要的一環就是「安全性」。我們必須確保使用者下載的更新檔確實是由我們發佈的,而不是被惡意竄改的版本。Updater 透過非對稱加密簽章來保證這一點。

執行流程如下:

  1. 開發者產生一組「公鑰」與「私鑰」。
  2. 公鑰 (Public Key) 會被打包進你的應用程式中。
  3. 私鑰 (Private Key) 由開發者妥善保管,絕對不能外洩
  4. 當你發佈新版本時,你會用「私鑰」對更新檔進行簽署 (Sign),產生一個獨一無二的簽章。
  5. 應用程式端的 Updater 用內建的「公鑰」去驗證這個簽章。如果驗證通過,代表更新檔是合法且未被竄改的,可以安全安裝。

這個金鑰設定是強制性的,若沒有設定,Updater 將無法運作。

設定金鑰

Tauri CLI 有提供工具來產生數位簽章用的公鑰、私鑰。指令如下:

npm run tauri signer generate

實作

通常都是在啟動時,直接在後端 Rust 進行版本檢查與更新:

use tauri_plugin_updater::UpdaterExt;

pub fn run() {
  tauri::Builder::default()
    .setup(|app| {
      let handle = app.handle().clone();
      tauri::async_runtime::spawn(async move {
        update(handle).await.unwrap();
      });
      Ok(())
    })
    .run(tauri::generate_context!())
    .unwrap();
}

async fn update(app: tauri::AppHandle) -> tauri_plugin_updater::Result<()> {
  if let Some(update) = app.updater()?.check().await? {
    let mut downloaded = 0;

    // alternatively we could also call update.download() and update.install() separately
    update
      .download_and_install(
        |chunk_length, content_length| {
          downloaded += chunk_length;
          println!("downloaded {downloaded} from {content_length:?}");
        },
        || {
          println!("download finished");
        },
      )
      .await?;

    println!("update installed");
    app.restart();
  }

  Ok(())
}

也可以在前端 JS 實作:

import { check } from '@tauri-apps/plugin-updater';
import { relaunch } from '@tauri-apps/plugin-process';

const update = await check();
if (update) {
  console.log(
    `found update ${update.version} from ${update.date} with notes ${update.body}`
  );
  let downloaded = 0;
  let contentLength = 0;
  // alternatively we could also call update.download() and update.install() separately
  await update.downloadAndInstall((event) => {
    switch (event.event) {
      case 'Started':
        contentLength = event.data.contentLength;
        console.log(`started downloading ${event.data.contentLength} bytes`);
        break;
      case 'Progress':
        downloaded += event.data.chunkLength;
        console.log(`downloaded ${downloaded} from ${contentLength}`);
        break;
      case 'Finished':
        console.log('download finished');
        break;
    }
  });

  console.log('update installed');
  await relaunch();
}

安全性考量

Tauri 的更新機制內建多重安全保護:

  • 數位簽章驗證:所有更新包都必須通過公鑰驗證
  • HTTPS 傳輸:確保更新檔案在傳輸過程中不被篡改
  • 使用者授權:更新安裝需要使用者明確同意

最佳實踐

  1. 定期檢查:建議在應用啟動時自動檢查更新,但不強制安裝
  2. 版本說明:提供清楚的更新說明,讓使用者了解新版本的改進
  3. 優雅降級:當更新伺服器無法連接時,應用程式仍能正常運行
  4. 使用者體驗:更新過程中提供進度提示,避免使用者困惑

小結

通過實作自動更新功能,你的 Tauri 應用將擁有更專業的使用者體驗,同時確保安全性和可維護性。這項功能不僅提升了應用的競爭力,更體現了對使用者負責的開發態度。


上一篇
[Day 25] Plugin (七):Biometric
系列文
用 Tauri 打造你的應用程式26
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言